<template>
	<div
		:class="[
			'app-editor-container',
			'app-array-box',
			`app-array-box-${name}`,
			disabled || readonly ? 'is-disabled' : null,
		]"
	>
		<template v-if="items.length == 0">
			<PlusCircleFilled class="app-array-box__icon add" @click="addItem()" />
		</template>
		<template v-else>
			<template v-for="(item, index) in items" :key="item.key">
				<div class="app-array-box__item">
					<AppInput
						v-if="Object.is(editorStyle, 'default')"
						:type="type"
						:size="size"
						:value="item.value"
						:maxLength="maxLength"
						:placeholder="placeholder"
						:disabled="disabled || readonly"
						:class="{ 'app-input--correct': item.correct }"
						:showMaxLength="showWordLimit"
						@component-action="(data:any) => handleInputEvent(data, index)"
					/>
					<a-tooltip
						v-else
						overlayClassName="app-array-box__tip"
						color="white"
						placement="bottom"
						trigger="hover"
					>
						<AppInput
							type="text"
							:size="size"
							:value="item.value"
							:placeholder="placeholder"
							:disabled="disabled || readonly"
							:class="{ 'app-input--correct': item.correct }"
							:beforeLabel="Object.is(editorStyle, 'url') ? prepend : null"
							:afterLabel="Object.is(editorStyle, 'url') ? append : null"
							:maxLength="Object.is(editorStyle, 'url') ? maxLength : null"
							:showMaxLength="
								Object.is(editorStyle, 'url') ? showWordLimit : null
							"
							@component-action="(data:any) => handleInputEvent(data, index)"
						/>
						<template #title v-if="!(!item.value || disabled || readonly)">
							<a-image
								v-if="Object.is(editorStyle, 'img')"
								:src="item.value"
								fallback="/assets/img/404.png"
							/>
							<a
								class="app-array-box-link"
								v-else
								:href="getUrl(item.value)"
								:target="target"
								>{{ getUrl(item.value) }}</a
							>
						</template>
					</a-tooltip>
					<div v-if="!(disabled || readonly)" class="app-array-box__icons">
						<PlusCircleFilled
							v-if="!limit || items.length < limit"
							class="app-array-box__icon add"
							@click="addItem(index + 1)"
						/>
						<MinusCircleFilled
							class="app-array-box__icon remove"
							@click="removeItem(index)"
						/>
					</div>
				</div>
			</template>
		</template>
	</div>
</template>
<script setup lang="ts">
import { Ref } from 'vue';
import { PlusCircleFilled, MinusCircleFilled } from '@ant-design/icons-vue';
import { arrayBoxProps } from './array-box';
import { createUUID, IEvent, IParam, VerifyUtil } from '@/core';
import { Form } from 'ant-design-vue';
import { useEditorTypeParams } from '@/hooks/use-editor';

interface EditorEmit {
	(name: 'component-action', value: IEvent<string>): void;
}

const props = defineProps(arrayBoxProps);
const emit = defineEmits<EditorEmit>();
// 类型校验
const { validateConfig } = useEditorTypeParams();
validateConfig();
/**
 * 数组数据
 */
const items: Ref<any> = ref([]);
/**
 * @description 通知表单表单校验当前项
 */
const triggerChange = () => {
	formItemContext.onFieldChange();
};
/**
 * 表单项上下文
 */
const formItemContext = Form.useInjectFormItemContext();

watch(
	() => props.value,
	(newVal: any, oldVal: any) => {
		if (newVal) {
			if (items.value.length == 0) {
				items.value = newVal.map((item: any) => {
					return {
						key: createUUID(),
						value: item,
					};
				});
			}
		} else {
			items.value = [];
		}
	},
	{
		immediate: true,
	}
);

/**
 * @description 添加编辑项
 * @param index 添加索引
 */
const addItem = (index?: number) => {
	if (props.disabled || props.readonly) {
		return;
	}
	const tempLink = {
		key: createUUID(),
		value: null,
	};
	if (index) {
		items.value.splice(index, 0, tempLink);
	} else {
		items.value.push(tempLink);
	}
	onEmit();
};

/**
 * @description 移除当前项
 * @param index 移除索引
 */
const removeItem = (index: number) => {
	items.value.splice(index, 1);
	onEmit();
};

/**
 * @description 获取url完整路径（前缀后缀）
 * @param value 值
 */
const getUrl = (value: string) => {
	let tempValue = value;
	if (tempValue) {
		if (props.prepend) {
			tempValue = props.prepend + tempValue;
		}
		if (props.append) {
			tempValue = tempValue + props.append;
		}
	}
	return tempValue;
};

/**
 * @description 处理input抛出事件
 * @param itemDate 项数据
 * @param index 项索引
 */
const handleInputEvent = (itemDate: any, index: number) => {
	const { action, data } = itemDate;
	switch (action) {
		case 'valueChange':
			handleChange(data, index);
			break;
		case 'editorBlur':
			onBlur(data);
			break;
		case 'editorFocus':
			onFocus(data);
			break;
	}
};

/**
 * @description 值改变
 * @param value 改变值
 * @param index 索引
 */
const handleChange = (value: any, index: number) => {
	items.value[index].value = value;
	onEmit();
	triggerChange();
	validatorData();
};

/**
 * @description 失焦
 * @param $event 参数
 */
const onBlur = ($event: any) => {
	const result = items.value.map((item: any) => item.value);
	triggerChange();
	emit('component-action', {
		name: `${props.name}`,
		action: 'editorBlur',
		data: result,
	});
};

/**
 * @description 聚焦
 * @param $event 参数
 */
const onFocus = ($event: any) => {
	const result = items.value.map((item: any) => item.value);
	emit('component-action', {
		name: `${props.name}`,
		action: 'editorFocus',
		data: result,
	});
};

/**
 * @description 抛出值改变
 */
const onEmit = () => {
	const result = items.value.map((item: any) => item.value);
	emit('component-action', {
		name: `${props.name}`,
		action: 'valueChange',
		data: result,
	});
};

/**
 * @description 校验数据
 */
const validatorData = async () => {
	for (let index = 0; index < items.value.length; index++) {
		try {
			await VerifyUtil.validateItem(
				props.name,
				{ [props.name]: items.value[index].value },
				{ [props.name]: props.rules }
			);
			items.value[index].correct = true;
		} catch (error) {
			items.value[index].correct = false;
		}
	}
};
</script>
